/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dipl.algorithm.math.primitive;

import dipl.algorithm.math.utility.FPMath;
import dipl.algorithm.math.utility.ApfloatUtils;
import org.apfloat.Apfloat;

/* vector in 2d real space */
public class Vector2d {

	//
	// CONSTRUCTOR METHODS
	//
	
	public Vector2d() {
		x = ApfloatUtils._0;
		y = ApfloatUtils._0;
	}

	public Vector2d( Apfloat x, Apfloat y ) {
		this.x = x;
		this.y = y;
	}

	public Vector2d( Vector2d other ) {
		x = other.x;
		y = other.y;
	}

	//
	// PUBLIC METHODS
	//

	/**
	 * Returns norm (euclidian norm) of vector
	 * @param norm
	 * @return
	 */
	public Apfloat Norm( FPMath fpMath ) {
		try {
			return fpMath.m.sqrt( SquareNorm( fpMath ) );
		}
		catch( ArithmeticException e ) {
			return fpMath._0;
		}
	}

	/*
	 * normalizes vector
	 */
	public void Normalize( FPMath fpMath ) {
		Apfloat len = Norm( fpMath );
		// len is  zero
		if( len.compareTo( fpMath._0 ) == 0 )
			return;
		x = fpMath.m.divide( x, len );
		y = fpMath.m.divide( y, len );
	}

	/**
	 *  Returns norm² (square of euclidian norm) of vector
	 */
	public Apfloat SquareNorm( FPMath fpMath ) {
		return fpMath.m.multiplyAdd( x, x, y, y );
	}

	/**
	 * 
	 * @param other
	 */
	public void Set( Vector2d other ) {
		x = other.x;
		y = other.y;
	}

	/**
	 * 
	 * @param x
	 * @param y
	 */
	public void Set( Apfloat x, Apfloat y ) {
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString() {
		return "[x:"+x.doubleValue()+", y:"+y.doubleValue()+"]";
	}

	//
	// MEMBERS
	//

	/** x-element */
	public Apfloat x;

	/** y-element */
	public Apfloat y;
}
